/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/
/* tcpgetspace.c - tcpgetspace */

#include "tcpfms.h"
#include "tcb.h"
#include "tcp.h"

/*------------------------------------------------------------------------
 *  tcpgetspace  -  wait for space in the send buffer
 *	N.B. - returns with tcb_mutex HELD
 *------------------------------------------------------------------------
 */
int tcpgetspace(struct tcb *ptcb, unsigned len)
{
    if (len > ptcb->tcb_sbsize)
            return TCPE_TOOBIG;	/* we'll never have this much	*/
    while (1) {
        sem_wait(&(ptcb->tcb_ssema));
        sem_wait(&(ptcb->tcb_mutex));
        if (ptcb->tcb_state == TCPS_FREE)
            return SYSERR;			/* gone		*/
        if (ptcb->tcb_error) {
            tcpwakeup(WRITERS, ptcb);	/* propagate it */
            sem_post(&(ptcb->tcb_mutex));
            return ptcb->tcb_error;
        }
        if (len <= ptcb->tcb_sbsize - ptcb->tcb_sbcount)
            return len;
        sem_post(&(ptcb->tcb_mutex));
    }
}
